<?php
namespace App\Service\ApiXcx;

use Illuminate\Support\Facades\DB;

class WxPayService extends BaseService
{
    //微信支付

    //通过token获取openid
    public function getOpenidByToken($token)
    {
        $resOne = (array) DB::table($this->dbUser)->where('token', $token)->first();
        if (empty($resOne)) {
            return array('code' => -2, 'msg' => '用户不存在');
        }
        return array('code' => 0, 'msg' => 'success', 'data' => $resOne);
    }

    //订单信息
    public function getOrderOne($type, $orderno)
    {
        if ($type == 1) {
            $res = (array) DB::table($this->dbUlevel)
                ->where('del', 0)
                ->where('id', $orderno)
                ->first();
        } else {
            $res = (array) DB::table($this->dbOrder)->where('orderno', $orderno)->first();
        }
        if (empty($res)) {
            return array('code' => -2, 'msg' => '订单不存在');
        }
        $price = $type== 1 ? $res['price'] : $res['real_pay'];
        if (!$price) {
            return array('code' => -2, 'msg' => '订单不能为0');
        }
        return array('code' => 0, 'msg' => 'success', 'data' => $price);
    }

    //获取礼品卡价格
    public function getCardPriceById($id){
        return DB::table($this->dbCardGoods)->where('id', $id)->value('price');
    }

    //添加到pay表
    public function payAdd($pas)
    {
        $pas['addtime'] = toDate();
        return DB::table($this->dbPay)->insertGetId($pas);
    }

    //更新pay表
    public function payModify($id, $pas)
    {
        $pas['uptime'] = toDate();
        return DB::table($this->dbPay)->where('id', $id)->update($pas);
    }

    //微信通知
    public function notice($wxdata)
    {
        $wxjson = [
            'wxjson' => json_encode($wxdata, JSON_UNESCAPED_UNICODE),
            'addtime' => toDate(),
        ];
        return DB::table($this->dbPayNotice)->insertGetId($wxjson);
    }

    //成功更新
    public function noticeModify($id, $out_trade_no)
    {
        $payOne = (array) DB::table($this->dbPay)->where('out_trade_no', $out_trade_no)->first();
        if (!empty($payOne) && $payOne['status'] == 2) {
            return $this->toback(-2, '已更新状态');
        }
        DB::beginTransaction(); //开启事务
        try {
            //更新通知
            DB::table($this->dbPayNotice)->where('id', $id)
                ->update(['out_trade_no' => $out_trade_no]);
            //更新支付状态
            $payData = [
                'status' => 2,
                'noticetime' => toDate(),
            ];
            DB::table($this->dbPay)->where('out_trade_no', $out_trade_no)->update($payData);
            //更新订单状态
            if (!empty($payOne) && !$payOne['balance'] && $payOne['type'] == 2) {
                DB::table($this->dbOrder)->where('orderno', $out_trade_no)
                    ->update([
                        //'real_pay' => $payOne['money'],
                        'status' => 2,
                        'paytime' => toDate(),
                    ]);
                //计算佣金
                $orderInfo = (array)DB::table($this->dbOrder)->where('orderno', $out_trade_no)->first();
                $uOne = (array) DB::table($this->dbUser)
                    ->where('id', $orderInfo['uid'])
                    ->first();
                //上级分佣收益
                if($uOne['parent_id']) {
                    $skuOlds = DB::table($this->dbOsku)
                        ->where('order_id', $orderInfo['id'])
                        ->get()
                        ->map(function ($value){
                            return (array)$value;
                        })
                        ->toArray();
                    $commission = 0;
                    foreach ($skuOlds as $sku){
                        $skuOne = (array) DB::table($this->dbGsku)->where('id', $sku['sku_id'])->first();
                        $commission_rate = $skuOne['commission_rate']/100;
                        $commission += $sku['price'] * $sku['num'] * $commission_rate;//sku总价*佣金比例
                    }
                    if ($commission) {
                        $incom_arr = [
                            'uid' => $uOne['parent_id'],
                            'orderno' => $orderInfo['orderno'],
                            'ordertime' => $orderInfo['addtime'],
                            'amount' => $commission,
                            'status' => 1,
                            'addtime' => toDate()
                        ];
                        DB::table($this->dbUserIncome)->insertGetId($incom_arr);//收益记录
//                    DB::table($this->dbUser)->where('id', $uOne['parent_id'])
//                        ->increment('settle_income', $commission); //只增加待结算收益
                    }
                    //团长收益累计
                    if ($commission) {
                        $uData = [
                            'income' => $uOne['income'] + $commission, //可提现的
                            'all_income' => $uOne['all_income'] + $commission, //总收益
                        ];
                        $this->dbConn($this->dbUser)->where('id', $uOne['parent_id'])->update($uData);
                    }
                }
            }
            //更新余额
            if (!empty($payOne) && !$payOne['balance'] && $payOne['uid']) {
                $uOne = (array) DB::table($this->dbUser)
                    ->where('id', $payOne['uid'])
                    ->first();
                $balance = empty($uOne) ? 0 : $uOne['balance'];
                $type = empty($payOne) ? 0 : $payOne['type'];
                $money = empty($payOne) ? 0 : $payOne['money'];
                if ($type == 1) {
                    $balance += $money;
                } else {
                    $balance -= $money;
                }
                $balance = $balance >= 0 ? $balance : 0;
                $payData = [
                    'balance' => $balance,
                ];
                DB::table($this->dbPay)->where('out_trade_no', $out_trade_no)->update($payData); //支付流水
                //更新会员余额、积分，type为1充值2下单
                if ($payOne['type'] == 1) {
                    //$outnos = explode('_', $out_trade_no);
                    DB::table($this->dbUser)->where('id', $payOne['uid'])
                        ->update([
                            'balance' => $balance,
                            //'level_id' => $outnos[0],
                            'uptime' => toDate(),
                        ]);
                    //处理充值积分
                    //$rate = getConfig('recharge_points_rate');
                    $rate = $this->getConfig('recharge_points_rate');
                    $rate = $rate['code']==0 ? $rate['data'] : 0;
                    $rate = $rate/100;
                    $points = $rate * $money;
                    $point_log = [
                        'uid' => $uOne['id'],
                        'type' => 3,
                        'before_points' => $uOne['points'],
                        'change_points' => $points,
                        'after_points' => ($uOne['points'] + $points),
                        'reason' => '充值送积分',
                        'relation_value' => $out_trade_no,
                        'addtime' => toDate()
                    ];
                    DB::table($this->dbUser)->where('id', $uOne['id'])->increment('points', $points);
                    DB::table($this->dbUserPointLog)->insertGetId($point_log);
                }
                //下单送积分
                if ($payOne['type'] == 2) {
                    $rate = $this->getConfig('order_points_rate');
                    $rate = $rate['code']==0 ? $rate['data'] : 0;
                    $rate = $rate/100;
                    $points = $rate * $money;
                    $point_log = [
                        'uid' => $uOne['id'],
                        'type' => 2,
                        'before_points' => $uOne['points'],
                        'change_points' => $points,
                        'after_points' => ($uOne['points'] + $points),
                        'reason' => '下单送积分',
                        'relation_value' => $out_trade_no,
                        'addtime' => toDate()
                    ];
                    DB::table($this->dbUser)->where('id', $uOne['id'])->increment('points', $points);
                    DB::table($this->dbUserPointLog)->insertGetId($point_log);
                }
                //礼品卡更新
                if($type == 3 && $payOne['status'] == 1){
                    $outnos = explode('_', $out_trade_no);
                    $card_param = $outnos[0];
                    $card_list = explode('|', $card_param);
                    foreach ($card_list as $card){
                        $card_data = explode('-', $card);
                        $card_info = (array)DB::table($this->dbCardGoods)->where('id', $card_data[0])->first();
                        if (!$card_info){
                            continue;
                        }
                        $card_user_data = [
                            'uid' => $payOne['uid'],
                            'card_id' => $card_info['card_id'],
                            'card_goods_id' => $card_info['id'],
                            'price' => $card_info['price'],
                            'num' => $card_data[1],
                            //'code' => $card_info['code'],
                            'code' => toCardCode(),
                            'addtime' => toDate(),
                            'uptime' => toDate()
                        ];
                        DB::table($this->dbCardUser)->insertGetId($card_user_data);
                        //送积分
                        $rate = $this->getConfig('card_points_rate');
                        $rate = $rate['code']==0 ? $rate['data'] : 0;
                        $rate = $rate / 100;
                        $points = $rate * $card_info['price'];
                        $point_log = [
                            'uid' => $uOne['id'],
                            'type' => 4,
                            'before_points' => $uOne['points'],
                            'change_points' => $points,
                            'after_points' => ($uOne['points'] + $points),
                            'reason' => '购买礼品卡送积分',
                            'relation_value' => $out_trade_no,
                            'addtime' => toDate()
                        ];
                        DB::table($this->dbUser)->where('id', $uOne['id'])->increment('points', $points);
                        DB::table($this->dbUserPointLog)->insertGetId($point_log);
                    }
                }
            }
            //更新用户累计消费和等级
//            $orderOne = (array)DB::table($this->dbOrder)
//                ->where('orderno', $out_trade_no)
//                ->first();
            if ($payOne['status'] == 1) {
                $uOne = (array) $this->dbConn($this->dbUser)
                    ->where('id', $payOne['uid'])
                    ->first();
                $uCost = empty($uOne) ? 0 : $uOne['real_cost']; //用户累计订单消费
//            $uLevelId = empty($uOne) ? 0 : $uOne['level_id'];
//            $levelOne = (array) $this->dbConn($this->dbUlevel)
//                ->where('id', $uLevelId)
//                ->first();
//            $uCost += $payOne['money'];
                $this->dbConn($this->dbUser)->where('id', $payOne['uid'])
                    ->update(['real_cost' => $uCost + $payOne['money']]);
            }
//            //更新用户等级
//            $levelNew = (array) $this->dbConn($this->dbUlevel)
//                ->where('del', 0)
//                ->where('type', 1)
//                ->where('real_cost', '<=', $uCost)
//                ->orderBy('real_cost', 'asc')
//                ->first();
////            if (!empty($levelNew) && $levelNew['id'] != $uLevelId
////                && !empty($levelOne) && $levelOne['type'] != 2 && in_array($uOne['is_auto'], [0, 2])) {
//            if (!empty($levelNew) && $levelNew['id'] != $uLevelId
//                && in_array($uOne['is_auto'], [0, 2]) && $payOne['type'] == 2) {
//                $this->dbConn($this->dbUser)->where('id', $payOne['uid'])
//                    ->update(['level_id' => $levelNew['id']]);
//            }
            DB::commit(); //提交事务
            return array('code'=>0, 'msg'=>'success');
        } catch (\Exception $e) {
            DB::rollBack(); //事务回滚
            echo $e->getMessage();
            return array('code'=>-1, 'msg'=>'操作失败');
        }
    }

    //更新销售量
    public function setGsale($orderno)
    {
        $orderOne = (array) $this->dbConn($this->dbOrder, ['orderno' => $orderno])->first();
        if (empty($orderOne)) {
            return $this->toback(-2, '没有订单');
        }
        $skuOnes = $this->dbConn($this->dbOsku, ['order_id' => $orderOne['id']])->get();
        if (!count($skuOnes)) {
            return $this->toback(-2, '没有订单SKU');
        }
        $gAry = [];
        foreach ($skuOnes as $v) {
            $v = (array) $v;
            $gSku = (array) $this->dbConn($this->dbGsku, ['id' => $v['sku_id']])->first();
            $this->dbModify($this->dbGsku, ['id' => $v['sku_id']], ['sale' => $gSku['sale'] + $v['num']]);
            $gAry[$v['gid']] = isset($gAry[$v['gid']]) ? $gAry[$v['gid']] + $v['num'] : $v['num'];
        }
        foreach ($gAry as $k => $v) {
            $gOne = (array) $this->dbConn($this->dbGoods, ['id' => $k])->first();
            $this->dbModify($this->dbGoods, ['id' => $k], ['sale' => $gOne['sale'] + $v]);
        }
        return $this->toback();
    }

    /**
     * 余额支付
     * @param string $token
     * @param string $orderno
     */
    public function payByBalance($token, $orderno)
    {
        //订单金额
        $orderOne = $this->dbQueryOne($this->dbOrder, ['orderno'=>$orderno]);
        if (empty($orderOne)) {
            return $this->toback(-2, '订单不存在');
        }
        if ($orderOne['iscancel'] > 1) {
            return $this->toback(-2, '订单取消中');
        }
        if ($orderOne['status'] > 2) {
            return $this->toback(-2, '订单在后续流程中');
        }
        if ($orderOne['status'] == 2) {
            return $this->toback(-2, '订单已完成支付');
        }
        $price = $orderOne['price'];
        //用户余额
        $uOne = $this->dbQueryOne($this->dbUser, ['token'=>$token]);
        if (empty($uOne)) {
            return $this->toback(-2, '用户不存在');
        }
        $balance = $uOne['balance'];
        if ($balance < $price) {
            //return $this->toback(-2, '用户余额不足');
            return $this->toback(-2, '余额不足，请更换支付方式');
        }
        try {
            //修改订单
            $this->dbModify($this->dbOrder, ['orderno'=>$orderno], [
                'pay_way' => 2,
                'real_pay' => $price,
                'status' => 2,
                'paytime' => toDate(),
            ]);
            //修改用户余额
            $this->dbModify($this->dbUser, ['id'=>$uOne['id']], [
                'balance' => $balance - $price,
                'uptime' => toDate(),
            ]);
            //计算收益
            if($uOne['parent_id']) {
                $skuOlds = DB::table($this->dbOsku)->where('order_id', $orderOne['id'])->get()->map(function ($value){
                    return (array)$value;
                })
                    ->toArray();
                $commission = 0;
                foreach ($skuOlds as $sku){
                    $skuOne = (array) DB::table($this->dbGsku)->where('id', $sku['sku_id'])->first();
                    $commission_rate = $skuOne['commission_rate']/100;
                    $commission += $sku['price'] * $sku['num'] * $commission_rate;//sku总价*佣金比例
                }
                $incom_arr = [
                    'uid' => $uOne['parent_id'],
                    'orderno' => $orderOne['orderno'],
                    'ordertime' => $orderOne['addtime'],
                    'amount' => $commission,
                    'status' => 1,
                    'addtime' => toDate()
                ];
                DB::table($this->dbUserIncome)->insertGetId($incom_arr);//收益记录
                DB::table($this->dbUser)->where('id', $uOne['parent_id'])->increment('settle_income', $commission);//只增加待结算收益
            }

            return $this->toback();
        } catch (\Exception $e) {
            echo $e->getMessage();
            return $this->toback(-2, 'error');
        }
    }

    /**
     * 获取订单
     * @param string $orderno 订单号
     */
    public function refundOrderOne($orderno)
    {
        $payWay = 0; //1微信，2余额
        $type = 0; //1会员充值，2商品下单
        $realPay = 0; //实际支付金额分
        $payOne = (array) $this->dbConn($this->dbPay)
            ->where('out_trade_no', $orderno)
            //->where('balance', '>', 0)
            ->where('status', 2)
            ->first();
        $orderOne = (array) $this->dbConn($this->dbOrder)->where('orderno', $orderno)->first();
        if (empty($payOne)) { //商品下单，余额支付
            if (empty($orderOne)) {
                return $this->toback(-2, '没有该订单');
            }
            if ($orderOne['status'] < 2) {
                return $this->toback(-2, '没有支付');
            }
            $payWay = 2;
            $type = 2;
            $realPay = $orderOne['real_pay'];
        } else { //微信支付
            $payWay = 1;
            $type = $payOne['type'];
            if ($type == 2 && empty($orderOne)) {
                return $this->toback(-2, '没有该订单');
            }
            if ($payOne['status'] < 2) {
                return $this->toback(-2, '没有支付');
            }
            $realPay = $payOne['money'];
        }
        if (!$realPay) {
            return $this->toback(-2, '没有支付金额');
        }
        $resData = [
            'payWay' => $payWay,
            'type' => $type,
            'realPay' => $realPay,
        ];
        return $this->toback(0, '', $resData);
    }

    /**
     * 余额退款
     * @param int $uid 用户ID
     * @param string $orderno 订单号
     * @param int $realPay 金额分
     */
    public function refundBalance($uid, $orderno, $realPay)
    {
        $uOne = (array) $this->dbConn($this->dbUser)->where('id', $uid)->first();
        if (empty($uOne)) {
            return $this->toback(-2, '没有登录');
        }
        $orderOne = (array) $this->dbConn($this->dbOrder)->where('id', $orderno)->first();
        if (empty($orderOne)) {
            return $this->toback(-2, '没有订单');
        }
        try {
            //退款添加
            $this->dbConn($this->dbPayRefund)->insertGetId([
                'uid' => $uid, 'pay_way' => 2,
                'out_trade_no' => $orderno, 'money' => $realPay,
                'addtime' => toDate(), 'noticetime' => toDate(),
            ]);
            //更新订单
            $this->dbConn($this->dbOrder)->where('orderno', $orderno)
                ->update([
                    'pay_way' => 1,
                    'real_pay' => 0,
                    'status' => 1,
                ]);
            if ($orderOne['pay_way'] == 1) {
                //更新用户余额
                $this->dbConn($this->dbUser)->where('id', $uid)
                    ->update([
                        'balance' => $uOne['balance'] + $realPay,
                    ]);
            }
            return $this->toback();
        } catch (\Exception $e) {
            echo $e->getMessage();
            return $this->toback(-1, 'error');
        }
    }

    /**
     * 微信退款
     * @param int $uid 用户ID
     * @param string $orderno 订单号
     * @param int $realPay 金额分
     * @param array $realPay 金额分
     */
    public function refundWx($uid, $out_refund_no, $orderno, $realPay, $wx_req)
    {
        $uOne = (array) $this->dbConn($this->dbUser)->where('id', $uid)->first();
        if (empty($uOne)) {
            return $this->toback(-2, '没有登录');
        }
        //退款添加
        $id = $this->dbConn($this->dbPayRefund)->insertGetId([
            'uid' => $uid, 'pay_way' => 1,
            'refundno' => $out_refund_no,
            'out_trade_no' => $orderno, 'money' => $realPay,
            'wx_req' => $wx_req,
            'addtime' => toDate(),
        ]);
        if (!$id) {
            return $this->toback(-2, '操作失败');
        }
        return $this->toback(0, '', $id);
//        try {
//            //退款添加
//            $id = $this->dbConn($this->dbPayRefund)->insertGetId([
//                'uid' => $uid, 'pay_way' => 1,
//                'refundno' => $out_refund_no,
//                'out_trade_no' => $orderno, 'money' => $realPay,
//                'wx_req' => $wx_req,
//                'addtime' => toDate(),
//            ]);
//            //更新订单
//            $this->dbConn($this->dbOrder)->where('orderno', $orderno)
//                ->update([
//                    'pay_way' => 1,
//                    'real_pay' => 0,
//                    'status' => 1,
//                ]);
//            //更新用户余额
//            $this->dbConn($this->dbUser)->where('id', $uid)
//                ->update([
//                    'balance' => $uOne['balance'] + $realPay,
//                ]);
//            return $this->toback(0, '', $id);
//        } catch (\Exception $e) {
//            echo $e->getMessage();
//            return $this->toback(-1, 'error');
//        }
    }

    /**
     * 微信退款更新
     * @param int $id
     * @param string $back
     */
    public function refundModify($id, $back)
    {
        return $this->dbConn($this->dbPayRefund)->where('id', $id)
            ->update([
                'wx_back' => json_encode($back, JSON_UNESCAPED_UNICODE),
                'noticetime' => toDate(),
            ]);
    }

    //微信退款通知
    public function refundNotice($wxdata)
    {
        $wxjson = [
            'wxjson' => $wxdata,
            'addtime' => toDate(),
        ];
        return DB::table($this->dbPayNotice2)->insertGetId($wxjson);
    }

    //微信退款通知更新2
    public function refundNoticeModify2($id, $wxdata)
    {
        return DB::table($this->dbPayNotice2)->where('id', $id)->update(['reqjson' => $wxdata]);
    }

    //微信退款通知更新
    public function refundNoticeModify($id, $orderno)
    {
        $orderOne = (array) $this->dbConn($this->dbOrder)->where('orderno', $orderno)->first();
        if (empty($orderOne)) {
            return $this->toback(-2, '没有订单');
        }
        if (!$orderOne['real_pay']) {
            return $this->toback(-2, '已退款，无需再退');
        }
//        $uOne = (array) $this->dbConn($this->dbUser)->where('id', $orderOne['uid'])->first();
//        if (empty($uOne)) {
//            return $this->toback(-2, '没有用户');
//        }
//        $realPay = $orderOne['real_pay'];
        try {
            //订单更新
            $up = DB::table($this->dbOrder)->where('orderno', $orderno)
                ->update(['real_pay' => 0, 'iscancel' => 3, 'canceltime' => toDate()]);
            if (!$up) {
                return $this->toback(-2, '订单更新失败', $up);
            }
//            //用户余额更新
//            $up = DB::table($this->dbUser)
//                ->where('id', $orderOne['uid'])
//                ->update(['balance' => $uOne['balance'] - $realPay]);
//            if (!$up) {
//                return $this->toback(-2, '用户余额更新失败', $up);
//            }
            //退款更新
            $up = DB::table($this->dbPayRefund)
                ->where('out_trade_no', $orderno)
                ->update(['status' => 2, 'noticetime' => toDate()]);
            if (!$up) {
                return $this->toback(-2, '退款状态更新失败', $up);
            }
            //退款通知更新
            $up = DB::table($this->dbPayNotice2)
                ->where('id', $id)
                ->update(['out_trade_no' => $orderno]);
            if (!$up) {
                return $this->toback(-2, '退款通知更新失败', $up);
            }
            return $this->toback();
        } catch (\Exception $e) {
            return $this->toback(-1, 'error', $e->getMessage());
        }
    }
}